# encoding: utf-8
"""
反编译文件
注：为了将文件显示成人类能看懂的方式，将会对文件的多个部位进行处理和改进
如将一些地方标上序号，分区做好标记，替换操作码等方式
"""
import pickle
import sys
import os
from loader.codes_loader import codes_dict
from Error.Error import send_error
from Compiler.Compiler import Compiler


parser_ctree_byte_code = lambda code: [
    [(codes_dict[j[0]], j[1]) for j in i] for i in code
]


def output_data(output):
    """将读出的数据按一定次序输出"""
    try:
        print("Version:", output[0])

        print("Codes:")
        for line_num, i in enumerate(parser_ctree_byte_code(output[1])):
            print("    ", line_num, ":", end="")
            for j in i:
                print(f"{j[0]}|{j[1]}, ", end="")
            print("\n", end="")

        print("\nValues:")
        for i in range(len(output[2])):
            print("    ", i, ":", output[2][i])

        print("\nNames:")
        for i in range(len(output[3])):
            print("    ", i, ":", output[3][i])

        print("\n")
    except IndexError:
        # ctree文件为假
        print("File is not a ctree file.")


def Dis(path):
    """解析文件"""
    print(f"From '{path}':")
    file = open(path, "rb")
    try:
        output = pickle.loads(file.read())
    except EOFError:
        # 文件为空，反序列化出错
        print(f"Error:File {path} is empty.")
    except:
        # 可能为tree文件
        try:
            file.close()
            with open(path, "r", encoding="UTF-8") as file:
                output = Compiler(file.read())
                output_data(output)
        except:
            print("CompilerError.")
    else:
        output_data(output)
        file.close()


if __name__ == "__main__":
    file_list = sys.argv[1:]
    for i in file_list:
        try:
            Dis(i)
        except:
            send_error("OpenFileError", i)
